﻿//makefile 中定义是否支持 加密功能
#ifdef PROXYENCRYPT
#include "VVSec_smapi.h"
#include "securev2v_smapi.h"
#endif
#include "TcpServerImpl.h"
#include "configure.h"
#include "proxyEncrypt.h"
#include "common.h"

#define  _LOG_PROXYENCRYPT_DEBUG(_id,_format,...)  SLT_LOG_DEBUG("[encrypt](%u)" _format,_id, ##__VA_ARGS__)
#define  _LOG_PROXYENCRYPT_INFO(_id,_format,...)  SLT_LOG_INFO("[encrypt](%u)" _format,_id, ##__VA_ARGS__)
#define  _LOG_PROXYENCRYPT_ERR(_id,_format,...)  SLT_LOG_ERR("[encrypt](%u)" _format,_id, ##__VA_ARGS__)

//makefile 中定义是否支持 加密功能,如果不支持加密，下面的接口定义解决编译问题
#ifndef PROXYENCRYPT
typedef int PKI_DATA;
typedef struct SECURE_INIT_st {             //初始化的参数
    char* pConfFilePath;           //配置文件的路径（只有路径，不包含文件名）
    unsigned int uConfFilePathLen;          //配置文件路径的长度
} SECURE_INIT;
int VVSec_Initlize(SECURE_INIT* pInit = nullptr){return 0;}
int VVSec_OpenDevice(int nDeviceId, void** ppDevice){return 0;}
int VVSec_LoginDevice(void* pDevice, PKI_DATA pinData){return 0;}
int securev2v_entrynet(void* pDevice, 
    unsigned char* ucDeviceID,
    unsigned int uiDeviceIDLength,
    unsigned char* ucnmID,
    unsigned int uinmIDLength,
    unsigned char* ucInData,
    unsigned int uiInDataLength, 
    unsigned char* ucOutData,
    unsigned int* puiOutDataLength)	
	{
		// if( ucInData == nullptr){
		// 	return 0x0000AAAA;
		// }
		// return 0;
		return -1;
	}
	int securev2v_syncKey(void* pDevice, 
    unsigned char* ucInData,
    unsigned int uiInDataLength, 
    unsigned char* ucOutData,
    unsigned int* puiOutDataLength)
	{
		// if( ucInData == nullptr){
		// 	return 0x0000AAAA;
		// }
		// return 0x0000AAAB;
		return -1;  //默认不支持
	}
	int securev2v_agreementZGKey(void* pDevice, 
        unsigned char* ucTrafficId,
        unsigned int uiTrafficIdLength,
        unsigned char* ucInData,
        unsigned int uiInDataLength, 
        unsigned char* ucOutData,
        unsigned int* puiOutDataLength)
		{
			// if(ucTrafficId){
			// 	return 0x0000AAAB;
			// }
			// return 0x0000AAAA;
			return -1;
		}
	int securev2v_symDecrypt(void* pDevice, 
		unsigned int uiCryptoType, 
		unsigned char* ucInData,
		unsigned int uiInDataLength, 
		unsigned char* ucOutData,
		unsigned int* puiOutDataLength){return -1;}
	int securev2v_symEncrypt(void* pDevice, 
		unsigned int uiCryptoType, 
		unsigned char* ucInData,
		unsigned int uiInDataLength, 
		unsigned char* ucOutData,
		unsigned int* puiOutDataLength){return -1;}
#endif

#define _proxy_cmd_v2v_entrynetReq      39    //代理加密: 入网请求
#define _proxy_cmd_v2v_entrynetResp     40    //代理加密: 入网请求应答
#define _proxy_cmd_v2v_synckeyReq      	41    //代理加密: 同步请求
#define _proxy_cmd_v2v_synckeyResp      42    //代理加密: 同步请求应答
#define _proxy_cmd_v2v_zgkeyReq      	45    //代理加密: zgkey请求
#define _proxy_cmd_v2v_zgkeyResp        46    //代理加密: zgkey应答
#define _proxy_cmd_local_startZgkey     47    //本地消息通知,开始协商key

#define _proxy_cmd_client_synckeyReq      	102    //向代理发送同步请求
#define _proxy_cmd_client_synckeyResp       103   //代理同步请求应答

//加密流程协议头
#pragma pack(1)


//消息sender协议头
struct SLTMacSenderProtocolHeadSt
{
	uint32_t  m_len;
	uint16_t  m_cmd;
	uint32_t  m_dstid;
	uint32_t  m_srcid;
	
	void toLocal() {
		m_len = SLT_ntohl(m_len);
		m_dstid = SLT_ntohl(m_dstid);
		m_srcid = SLT_ntohl(m_srcid);
		m_cmd = SLT_ntohs(m_cmd);
	}
	void toNet() {
		m_len = SLT_htonl(m_len);
		m_dstid = SLT_htonl(m_dstid);
		m_srcid = SLT_htonl(m_srcid);
		m_cmd = SLT_htons(m_cmd);
	}
	std::string toString() {
		char buf[128] = {0};
		snprintf(buf, sizeof(buf), "%u,%u,%u,%u", m_len, m_cmd, m_dstid, m_srcid);
		return std::string(buf);
	}
};


//加密连接信息
//_proxy_cmd_v2v_entrynetReq
struct _proxy_cmd_v2v_entrynetReq_st
{
	void reset(){
		memset(ucDeviceID,0,sizeof(ucDeviceID));
		memset(ucnmID,0,sizeof(ucnmID));
	}

	slt_uuid_t uuid;
	uint32_t   m_index = 0;

	//unsigned char m_srcID[6];  //使用mac作为身份标识
	//unsigned char m_dstaddr[6];

	unsigned char ucDeviceID[32] = {0};  //字符串，不包括\0
	unsigned char ucnmID[32] = {0};
	int  respcode = 0;  //应答错误码
	int  encrypt_code;  //加密错误码
};

//加密协商应答
struct _proxy_cmd_v2v_encryptResp_st
{
	slt_uuid_t uuid;
	uint32_t   m_index = 0;
	
	int code;  //0-成功，其他失败
	int encrypt_code;  //密码库错误
};
typedef _proxy_cmd_v2v_encryptResp_st _proxy_cmd_v2v_syncKeyReq_st;
typedef _proxy_cmd_v2v_encryptResp_st _proxy_cmd_v2v_syncKeyResp_st;
typedef _proxy_cmd_v2v_encryptResp_st _proxy_cmd_v2v_getZgKeyReq_st;
typedef _proxy_cmd_v2v_encryptResp_st _proxy_cmd_v2v_getZgKeyResp_st;

#pragma pack()

//_proxy_cmd_client_synckeyReq 102  ，应答103
//格式 _proxy_cmd_client_synckeyReq_st|strjson(_proxy_cmd_client_synckeyReq_json_st)|二进制数据
struct _proxy_cmd_client_synckeyReq_json_st
{
	std::string sid;
	AIGC_JSON_HELPER(sid)
};
struct _proxy_cmd_client_synckeyResp_json_st
{
	int   ret;
	std::string  sessionid;
	std::string  ret_msg;
	AIGC_JSON_HELPER(ret, sessionid, ret_msg)
};
#pragma pack(1)
struct _proxy_cmd_client_synckeyReq_st
{
	short jsonlen;
	short datalen;
};
#pragma pack()

void CProxyEncryptInitSession::OnStart()
{
	_sendProxyClientsyncKey();
	setTimer(1,3000,false); 
}
void CProxyEncryptInitSession::OnMsgArrive(SLF_senderPtr &_sender,uint32_t srcSid, int msgid,SLF_sendMemBasePtr &_data)
{
	if(msgid == _proxy_cmd_client_synckeyResp){
		OnProxyClientsyncKeyResp(_sender,srcSid,msgid,_data);
	}else{
		SLT_LOG_ERR("encrypt msg unknonw:%d",msgid);
	}
}
void CProxyEncryptInitSession::OnTimer(uint32_t timerID, int _intervalMs, bool periodic)
{
	_sendProxyClientsyncKey();
	setTimer(1,3000,false);  
}
void CProxyEncryptInitSession::_sendProxyClientsyncKey()
{        
	//尝试初始化加密中间件，如果本地初始化(没有密管)，则向指定服务发送请求
	if(m_sendmem){
		//重发
		SLT_LOG_INFO("encrypt syncKey resend");
		m_senderSptr->SLF_postMsg(0, _proxy_cmd_client_synckeyReq, getSessID(), m_sendmem);
		return;
	}
	SLT_memDataSptr memdata(SLT_memData::newData(4096));
	int nret = securev2v_syncKey( CProxyEncryptManage::getInst()->m_deviceHandle,nullptr,0,(unsigned char*)memdata->m_pbuf,&memdata->m_size);
	if(0 == nret){
		SLT_LOG_INFO("encrypt syncKey success. local init success");
		SLF_delSession(getSessID());
		return;
	}
	if(nret != 0x0000AAAA){
		SLT_LOG_INFO("encrypt syncKey error,ret:%X",nret);
		return;
	}
		
	slt_uuid_t uuid;
	slt_uuid_create(&uuid);
	m_lastsid = slt_uuid_to_string(&uuid);

	_proxy_cmd_client_synckeyReq_json_st reqJson;
	reqJson.sid = m_lastsid;
	std::string strJson;
	aigc::JsonHelper::ObjectToJson(reqJson, strJson);

	_proxy_cmd_client_synckeyReq_st req;
	req.datalen = memdata->m_size;
	req.jsonlen = strJson.length();

	SLT_memBuf membuf;
	membuf.resize(sizeof(_proxy_cmd_client_synckeyReq_st) + req.jsonlen + req.datalen);
	membuf.append((char*)&req, sizeof(req));
	membuf.append(strJson.c_str(), req.jsonlen);
	membuf.append(memdata->m_pbuf,req.datalen);

	SLT_LOG_INFO("encrypt syncKey req, dst(%s:%d),data:%s,datalen:%d",	proxy_ip.c_str(),proxy_port, strJson.c_str(),req.datalen);
	//发送同步请求
	if(! m_senderSptr){
		m_senderSptr = CCacTcpServer::getInst()->getProxyCfgSender(proxy_ip,proxy_port);
	}
	m_sendmem.reset(new SLF_sendMemBase);
	m_sendmem->m_mem = membuf;
	m_senderSptr->SLF_postMsg(0, _proxy_cmd_client_synckeyReq, getSessID(), m_sendmem);
}
void CProxyEncryptInitSession::OnProxyClientsyncKeyResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{	
	//加密中间件初始化应答
	_proxy_cmd_client_synckeyReq_st* preq = (_proxy_cmd_client_synckeyReq_st*)_data->getData();
	if (_data->getLen() != sizeof(_proxy_cmd_client_synckeyReq_st) + preq->jsonlen + preq->datalen) {
		SLT_LOG_ERR("encrypt syncKey resp,len error");
		SLT_LOG_ERR("encrypt syncKey resp,jsonlen:%d,datalen:%d", preq->jsonlen, preq->datalen);
		return;
	}

	SLT_LOG_ERR("encrypt syncKey resp ,json:%s", _data->getData() + sizeof(_proxy_cmd_client_synckeyReq_st));
	_proxy_cmd_client_synckeyResp_json_st respJson;
	std::string jsonErr;
	if (!aigc::JsonHelper::JsonToObject3(respJson, _data->getData() + sizeof(_proxy_cmd_client_synckeyReq_st), preq->jsonlen, {}, &jsonErr)) {
		SLT_LOG_ERR( "encrypt syncKey resp ,json error:%s", jsonErr.c_str());
		return;
	}
	if(m_lastsid != respJson.sessionid){
		SLT_LOG_ERR("encrypt syncKey resp error,sid:%s", m_lastsid.c_str());
		return;
	}

	if(respJson.ret != 0){
		SLT_LOG_ERR("encrypt syncKey resp error,json:%s", _data->getData() + sizeof(_proxy_cmd_client_synckeyReq_st));
		return;
	}

	unsigned char *precvdata = (unsigned char*)_data->getData() + sizeof(_proxy_cmd_client_synckeyReq_st) + preq->jsonlen;
	SLT_memDataSptr memdata(SLT_memData::newData(4096));
	int nret = securev2v_syncKey( CProxyEncryptManage::getInst()->m_deviceHandle,precvdata,preq->datalen,(unsigned char*)memdata->m_pbuf,&memdata->m_size);
	if(0 == nret){
		SLT_LOG_INFO("encrypt syncKey resp success");
		SLF_delSession(getSessID());
		return;
	}

	SLT_LOG_INFO("encrypt syncKey error,ret:%d",nret);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CProxyEncrypt::CProxyEncrypt()
{
	slt_uuid_create(&m_uuid);
}
int CProxyEncrypt::entryNetStart(SLT_memDataSptr &_out_memData)
{	
	//第一次发起
	//numid 为上级唯一id： 使用自治前缀
	_out_memData.reset(SLT_memData::newData(4096));
	
	_proxy_cmd_v2v_entrynetReq_st *preq = (_proxy_cmd_v2v_entrynetReq_st*)_out_memData->m_pbuf;
	preq->reset();

	//MacType &_mac
	//ucDeviceID 使用本地物理mac，ucnmID使用父级mac
	//CV2vJoinProxyConfig* pconfig = CV2vJoinProxyConfig::getInst();
	char ascbuf[64] = { 0 };
    snprintf(ascbuf, sizeof(ascbuf), "lan_dev_mac%021d",1);
    _LOG_PROXYENCRYPT_ERR(0, "sunning1 : %s-%d", ascbuf, strlen(ascbuf));
	memcpy(preq->ucDeviceID,ascbuf,sizeof(preq->ucDeviceID));  //严格32个字节的字符串，没有\0
	snprintf(ascbuf, sizeof(ascbuf), "lan_nm_up_mac%019d",1); //严格32个字节的字符串，没有\0
    _LOG_PROXYENCRYPT_ERR(0, "sunning2 : %s-%d", ascbuf, strlen(ascbuf));
	memcpy(preq->ucnmID,ascbuf,sizeof(preq->ucnmID));
	_LOG_PROXYENCRYPT_ERR(0,"entrynet start,devid:%s,nmid:%s",SLT_AscToHex2((char*)preq->ucDeviceID,sizeof(preq->ucDeviceID)).c_str(),SLT_AscToHex2((char*)preq->ucnmID,sizeof(preq->ucnmID)).c_str());
	
	uint32_t  memsize = _out_memData->m_size - sizeof(_proxy_cmd_v2v_entrynetReq_st);
	int nret = securev2v_entrynet(CProxyEncryptManage::getInst()->m_deviceHandle, 
                                preq->ucDeviceID,
                                sizeof(preq->ucDeviceID),
								preq->ucnmID,
                                sizeof(preq->ucnmID),
                                NULL,
                                0, 
                                (unsigned char*)_out_memData->m_pbuf + sizeof(_proxy_cmd_v2v_entrynetReq_st),
                                &memsize);
	_out_memData->m_size = memsize + sizeof(_proxy_cmd_v2v_entrynetReq_st);
	return nret;
}
int CProxyEncrypt::entryNet(char *_pdata,int _len,SLT_memDataSptr &_out_memData)
{
	_proxy_cmd_v2v_entrynetReq_st *preq = (_proxy_cmd_v2v_entrynetReq_st*)_pdata;
	int recvlen = _len - sizeof(_proxy_cmd_v2v_entrynetReq_st);

	_LOG_PROXYENCRYPT_ERR(0,"entrynet,devid:%s,nmid:%s",SLT_AscToHex2((char*)preq->ucDeviceID,sizeof(preq->ucDeviceID)).c_str(),SLT_AscToHex2((char*)preq->ucnmID,sizeof(preq->ucnmID)).c_str());
	//入网协商中的处理
	_out_memData.reset(SLT_memData::newData(4096));
    memcpy(_out_memData->m_pbuf, _pdata, sizeof(_proxy_cmd_v2v_entrynetReq_st));
	
    printf("??????????????????????????????????????????????? \n\n");
    dump_payload(_out_memData->m_pbuf, sizeof(_proxy_cmd_v2v_entrynetReq_st));

	uint32_t  memsize = _out_memData->m_size - sizeof(_proxy_cmd_v2v_entrynetReq_st);
	int nret = securev2v_entrynet(CProxyEncryptManage::getInst()->m_deviceHandle, 
                                preq->ucDeviceID,
                                sizeof(preq->ucDeviceID),
                                preq->ucnmID,
                                sizeof(preq->ucnmID),
                                (unsigned char*)_pdata + sizeof(_proxy_cmd_v2v_entrynetReq_st),
                                recvlen, 
                                (unsigned char*)_out_memData->m_pbuf + sizeof(_proxy_cmd_v2v_entrynetReq_st),
                                &memsize);
	_out_memData->m_size = memsize + sizeof(_proxy_cmd_v2v_entrynetReq_st);
	return nret;
}

/*************************************************************************************************************************************************/
void CProxyServiceCascadeChild::OnStart()
{
	m_delTimer.start();
	m_id = getSessID();
	setTimer(1,1000,false);
}
void CProxyServiceCascadeChild::OnStop()
{
	_LOG_PROXYENCRYPT_ERR(m_id,"stop");
}
void CProxyServiceCascadeChild::OnTimer(uint32_t timerID, int _intervalMs, bool periodic)
{
	setTimer(1,1000,false);
	m_recvCheck.checkState();

	if(m_delTimer.elapseMs() > 60000){
		CProxyEncryptManage::getInst()->delchild(this);
	}
}
void CProxyServiceCascadeChild::OnMsgArrive(SLF_senderPtr &_sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr &_data)
{
	m_delTimer.start();
	switch (msgid){
		SLF_MSGARRIVE(_proxy_cmd_v2v_entrynetReq,OnRecvEntrynetReq);
		SLF_MSGARRIVE(_proxy_cmd_v2v_synckeyReq,OnRecvSynckeyReq);
		SLF_MSGARRIVE(_proxy_cmd_v2v_zgkeyReq,OnGetzgkeyReq);		
	default:
		_LOG_PROXYENCRYPT_ERR(m_id,"CProxyServiceCascadeChild unknown msg:%d", msgid);
		break;
	}
}

void CProxyServiceCascadeChild::OnRecvEntrynetReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	_proxy_cmd_v2v_entrynetReq_st *preq = (_proxy_cmd_v2v_entrynetReq_st*)_data->getData();
	_LOG_PROXYENCRYPT_DEBUG(m_id,"recv entrynet,index:%u,uuid:%s",preq->m_index,slt_uuid_to_string(&preq->uuid).c_str());

	//连接重新开始
	if(m_uuid != preq->uuid){
		m_recvCheck.clear();
	}
    m_uuid = preq->uuid;

	SLT_recvRepeatCheckUserDataSptr recvMem;
	m_recvCheck.checkRecv(preq->m_index,recvMem);
	if(recvMem){
		//重复接收，直接应答
		_LOG_PROXYENCRYPT_DEBUG(m_id,"recv entrynet again,uuid:%s",slt_uuid_to_string(&preq->uuid).c_str());
		SLF_sendMemBasePtr sendmem(new SLF_sendMemBase());
		sendmem->m_mem = recvMem->m_data;
		_sender->SLF_postMsg(srcSid,_proxy_cmd_v2v_entrynetResp,getSessID(),sendmem);
		return;
	}

	char *precvData = _data->getData() ;
	int   recvlen = _data->getLen();
	SLT_memDataSptr _out_memData;
	int nret = entryNet(precvData,recvlen,_out_memData);
	_proxy_cmd_v2v_entrynetReq_st *presp = (_proxy_cmd_v2v_entrynetReq_st*)_out_memData->m_pbuf;
	presp->encrypt_code = nret;
	if(nret == 0x0000AAAB || nret == 0x0000AAAD){
		presp->respcode = 0;
		_LOG_PROXYENCRYPT_DEBUG(m_id,"entrynet return ack");
		m_work_state = encrypt_state_entrynet;
	}else{
		_out_memData->m_size = sizeof(_proxy_cmd_v2v_entrynetReq_st);
		presp->respcode = -1;
		_LOG_PROXYENCRYPT_ERR(m_id,"recv entrynet error : %X", nret);
	}
	presp->m_index = preq->m_index;
	presp->uuid = m_uuid;

    printf("8888888888888888888888888888888888 \n");
    dump_payload(_out_memData->m_pbuf, _out_memData->m_size);

	SLF_sendMemBasePtr sendmem(new SLF_sendMemBase());
	sendmem->m_mem.add((char*)_out_memData->m_pbuf,_out_memData->m_size);
	SLT_recvRepeatCheckUserDataSptr savemem = std::make_shared<SLT_recvRepeatCheckUserData>();
	savemem->m_data = sendmem->m_mem;
	m_recvCheck.save2(preq->m_index,savemem);

	_sender->SLF_postMsg(srcSid,_proxy_cmd_v2v_entrynetResp,getSessID(),sendmem);
	//SLCS_sendRespData(reqIndex,_proxy_cmd_v2v_entrynetResp,(char*)_out_memData->m_pbuf,_out_memData->m_size);
}
void CProxyServiceCascadeChild::OnRecvSynckeyReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	_proxy_cmd_v2v_syncKeyReq_st *preq = (_proxy_cmd_v2v_syncKeyReq_st*)_data->getData();
	_LOG_PROXYENCRYPT_INFO(m_id,"recv synckey,index:%u,recvuuid:%s",preq->m_index,slt_uuid_to_string(&preq->uuid).c_str());
	std::string synckeyData =  SLT_AscToHex2(_data->getData(),_data->getLen());
	_LOG_PROXYENCRYPT_DEBUG(m_id,"recv datalen:%u,alldata:%s",_data->getLen(),synckeyData.c_str());
	if(m_uuid != preq->uuid){
		_LOG_PROXYENCRYPT_ERR(m_id,"recv synckey error,uuid error");
		return;
	}

	SLT_recvRepeatCheckUserDataSptr recvMem;
	m_recvCheck.checkRecv(preq->m_index,recvMem);
	if(recvMem){
		//重复接收，直接应答
		SLF_sendMemBasePtr sendmem(new SLF_sendMemBase());
		sendmem->m_mem = recvMem->m_data;
		_sender->SLF_postMsg(srcSid,_proxy_cmd_v2v_synckeyResp,getSessID(),sendmem);
		return;
	}
    char* precvData = _data->getData()+ sizeof(_proxy_cmd_v2v_syncKeyReq_st);
    int   recvlen = _data->getLen() - sizeof(_proxy_cmd_v2v_syncKeyReq_st);
	std::string synckeyUseData =  SLT_AscToHex2(precvData,recvlen);
	_LOG_PROXYENCRYPT_DEBUG(m_id,"recv synckey datalen:%u,data:%s",recvlen,synckeyUseData.c_str());
	SLT_memDataSptr _out_memData(SLT_memData::newData(4096));
	_proxy_cmd_v2v_syncKeyResp_st *presp = (_proxy_cmd_v2v_syncKeyResp_st*)_out_memData->m_pbuf;
	uint32_t outLen = _out_memData->m_size - sizeof(_proxy_cmd_v2v_syncKeyResp_st);
	int nret = securev2v_syncKey(CProxyEncryptManage::getInst()->m_deviceHandle, (unsigned char*)precvData, recvlen,
								(unsigned char*)_out_memData->m_pbuf + sizeof(_proxy_cmd_v2v_syncKeyResp_st), &outLen);
	presp->encrypt_code = nret;
	if(nret == 0x0000AAAB){
		//发送同步命令应答
		_out_memData->m_size = outLen + sizeof(_proxy_cmd_v2v_syncKeyResp_st);
		presp->code = 0;
		_LOG_PROXYENCRYPT_DEBUG(m_id,"recv synckey return ack,len:%d",_out_memData->m_size);
		m_work_state = encrypt_state_syckey;
	}else{
		_out_memData->m_size = sizeof(_proxy_cmd_v2v_syncKeyResp_st);
		presp->code = -1;
		_LOG_PROXYENCRYPT_ERR(m_id,"recv synckey return error: %X",nret);
	}
	presp->m_index = preq->m_index;
	presp->uuid = m_uuid;

	SLF_sendMemBasePtr sendmem(new SLF_sendMemBase());
	sendmem->m_mem.add((char*)_out_memData->m_pbuf,_out_memData->m_size);
	SLT_recvRepeatCheckUserDataSptr savemem = std::make_shared<SLT_recvRepeatCheckUserData>();
	savemem->m_data = sendmem->m_mem;
	m_recvCheck.save2(preq->m_index,savemem);

	_sender->SLF_postMsg(srcSid,_proxy_cmd_v2v_synckeyResp,getSessID(),sendmem);
	//SLCS_sendRespData(reqIndex,_proxy_cmd_v2v_synckeyResp,(char*)_out_memData->m_pbuf,_out_memData->m_size);
}
void CProxyServiceCascadeChild::OnGetzgkeyReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	_proxy_cmd_v2v_getZgKeyReq_st *preq = (_proxy_cmd_v2v_getZgKeyReq_st*)_data->getData();
	_LOG_PROXYENCRYPT_INFO(m_id,"recv getzgkey,index:%u,,recvuuid:%s",preq->m_index,slt_uuid_to_string(&preq->uuid).c_str());
	_LOG_PROXYENCRYPT_DEBUG(m_id,"recv getzgkey,memdatalen:%u",_data->getLen());
	if(m_uuid != preq->uuid){
		_LOG_PROXYENCRYPT_ERR(m_id,"recv getzgkey error,uuid error");
		return;
	}

	SLT_recvRepeatCheckUserDataSptr recvMem;
	m_recvCheck.checkRecv(preq->m_index,recvMem);
	if(recvMem){
		//重复接收，直接应答
		SLF_sendMemBasePtr sendmem(new SLF_sendMemBase());
		sendmem->m_mem = recvMem->m_data;
		_sender->SLF_postMsg(srcSid,_proxy_cmd_v2v_zgkeyResp,getSessID(),sendmem);
		return;
	}
	char *precvData = _data->getData() + sizeof(_proxy_cmd_v2v_getZgKeyReq_st);
	int   recvlen = _data->getLen() - sizeof(_proxy_cmd_v2v_getZgKeyReq_st);
	dump_payload(precvData,100);
	_LOG_PROXYENCRYPT_DEBUG(m_id,"recv getzgkey,recvlen:%u,precvData:%s",recvlen,precvData);
	unsigned char traffid[32];  //接口要求，随便给个值就行,内部无关联
	traffid[0] = 1;
	SLT_memDataSptr memdata(SLT_memData::newData(4096));
	_proxy_cmd_v2v_getZgKeyResp_st *presp = (_proxy_cmd_v2v_getZgKeyResp_st*)memdata->m_pbuf;
	uint32_t outlen = memdata->m_size - sizeof(_proxy_cmd_v2v_getZgKeyResp_st);
	int nret = securev2v_agreementZGKey(CProxyEncryptManage::getInst()->m_deviceHandle, traffid,sizeof(traffid),(unsigned char *)precvData,recvlen,
								(unsigned char *)memdata->m_pbuf + sizeof(_proxy_cmd_v2v_getZgKeyResp_st),&outlen);
	presp->encrypt_code = nret;
	if(nret == 0x0000AAAB){
		memdata->m_size = outlen + sizeof(_proxy_cmd_v2v_getZgKeyResp_st);
		presp->code = 0;
		_LOG_PROXYENCRYPT_INFO(m_id,"getzgkey req ack");
		m_work_state = encrypt_state_getzgkey;
	}else{
		memdata->m_size = sizeof(_proxy_cmd_v2v_getZgKeyResp_st);
		presp->code = -1;
		_LOG_PROXYENCRYPT_ERR(m_id,"getzgkey req error: %X", nret);
	}
	presp->m_index = preq->m_index;
	presp->uuid = m_uuid;

	SLF_sendMemBasePtr sendmem(new SLF_sendMemBase());
	sendmem->m_mem.add((char*)memdata->m_pbuf,memdata->m_size);
	SLT_recvRepeatCheckUserDataSptr savemem = std::make_shared<SLT_recvRepeatCheckUserData>();
	savemem->m_data = sendmem->m_mem;
	m_recvCheck.save2(preq->m_index,savemem);

	_sender->SLF_postMsg(srcSid,_proxy_cmd_v2v_zgkeyResp,getSessID(),sendmem);
	//SLCS_sendRespData(reqIndex,_proxy_cmd_v2v_zgkeyResp,(char*)memdata->m_pbuf,memdata->m_size);
}

/*************************************************************************************************************************************************/
CProxyServiceCascade::CProxyServiceCascade()
{
	m_resendlist.setCB(this);
}
void CProxyServiceCascade::OnStart()
{
	m_resendTimer.start();
	m_id = getSessID();
	setTimer(1,1000,false);

	SLT_LOG_WARM("CProxyServiceCascade::OnStart, config up mac:%s",m_parentMac.toString().c_str());
	if(m_parentMac != MacType()){
		_entryNetStart();
	} 
}
void CProxyServiceCascade::OnTimer(uint32_t timerID, int _intervalMs, bool periodic)
{
	setTimer(1,1000,false);
	checkState();
	m_resendlist.check();
}

void CProxyServiceCascade::OnMsgArrive(SLF_senderPtr &_sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr &_data)
{
	switch (msgid){
		//SLF_MSGARRIVE(_proxy_cmd_v2v_connectReq,recvConnect);
		//SLF_MSGARRIVE(_proxy_cmd_v2v_csMsg,SLCS_recvConnectMsg);
		SLF_MSGARRIVE(_proxy_cmd_v2v_entrynetResp,OnRecvEntrynetResp);
		SLF_MSGARRIVE(_proxy_cmd_v2v_synckeyResp,OnRecvSynckeyResp);
		SLF_MSGARRIVE(_proxy_cmd_v2v_zgkeyResp,OnGetzgkeyResp);
		SLF_MSGARRIVE(_proxy_cmd_local_startZgkey,OnLocalGetzgkeyReq);
		
	default:
		_LOG_PROXYENCRYPT_ERR(0,"Cascade,unknown msg:%d,srcid:%u", msgid,srcSid);
		if(_data){
			_LOG_PROXYENCRYPT_ERR(0,"Cascade,unknown msg:%d,len:%d,data:%s",msgid,_data->getLen(),SLT_AscToHex2(_data->getData(),_data->getLen()).c_str());
		}
		break;
	}
}
void CProxyServiceCascade::checkState()
{
	//1s 定时器
	if(m_resendTimer.elapseMs() > 5000){
		m_resendTimer.start();
		if(m_work_sub_state == en_work_sub_state_start){
			if(m_work_state == encrypt_state_entrynet){
				_entryNetStart();
			}else if(m_work_state == encrypt_state_syckey){
				_syncKeyStart();
			}else if(m_work_state == encrypt_state_getzgkey){
				_getZgkeyStart();
			}
		}
	}
}
void CProxyServiceCascade::SLT_RLResend(SLT_resendList* _plist,SLT_resendItemCL*pitem)
{
	SLT_LOG_WARM("CProxyServiceCascade resend:cmd:%d",pitem->m_type);
	//命令重复
	SLF_sendMemBasePtr  sendData(new SLF_sendMemBase());
	sendData->m_mem = pitem->m_userdata->m_data;
	m_serversenderSptr->SLF_postMsg(m_parentSessID,pitem->m_type,getSessID(),sendData);
}
bool CProxyServiceCascade::_checkResp(uint32_t _index,slt_uuid_t &_uuid)
{
	SLT_resendItemCL *pitem = m_resendlist.find(_index);
	if(nullptr == pitem){
		_LOG_PROXYENCRYPT_ERR(m_id,"resp error. index no exsit.%u",_index);
		return false;
	}
	if(_uuid != m_uuid){
		_LOG_PROXYENCRYPT_ERR(m_id,"resp error. uuid no same, local:%s,recv:%s",
		slt_uuid_to_string(&m_uuid).c_str(),slt_uuid_to_string(&_uuid).c_str());
		return false;
	}
	return true;
}
void CProxyServiceCascade::OnRecvEntrynetResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	_proxy_cmd_v2v_entrynetReq_st *presp = (_proxy_cmd_v2v_entrynetReq_st*)_data->getData();
	if(! _checkResp(presp->m_index,presp->uuid)){
		return;
	}
	m_resendlist.del(presp->m_index);
	_LOG_PROXYENCRYPT_DEBUG(m_id,"entrynet resp ,index:%d,respcode:%d",presp->m_index,presp->respcode);

	//应答失败，重新开始
	if(presp->respcode != 0){
		m_work_sub_state = en_work_sub_state_start;  //重新开始
		_LOG_PROXYENCRYPT_DEBUG(m_id,"entrynet resp error,encrypt_code:%X",presp->encrypt_code);
		return;
	}
	m_parentSessID = srcSid; //保存父id

    char* precvData = _data->getData();// +sizeof(_proxy_cmd_v2v_entrynetReq_st);
    int   recvlen = _data->getLen();// -sizeof(_proxy_cmd_v2v_entrynetReq_st);
	SLT_memDataSptr memdata;
    _LOG_PROXYENCRYPT_ERR(0, "*****************************************************");
    dump_payload(precvData, recvlen);
	int nret = entryNet(precvData,recvlen,memdata);
	if(nret == 0){
		//协商完成
		_LOG_PROXYENCRYPT_ERR(m_id,"entrynet success");
		_syncKeyStart();
		return;
	}else if(nret == 0x0000AAAA){
		//发送入网请求
		//SLCS_sendReqData(_proxy_cmd_v2v_entrynetReq,std::to_string(_proxy_cmd_v2v_entrynetReq), 1000,-1,memdata->m_pbuf,memdata->m_size,&req_index);
		_proxy_cmd_v2v_entrynetReq_st *preq = (_proxy_cmd_v2v_entrynetReq_st*)memdata->m_pbuf;
		preq->uuid  = m_uuid;
		preq->m_index = m_cmdindexbase++;

		SLT_resendListUserDataSptr   resenddata = std::make_shared<SLT_resendListUserData>();
		resenddata->m_data.add(memdata->m_pbuf,memdata->m_size);
		m_resendlist.add2(preq->m_index,_proxy_cmd_v2v_entrynetReq,1000,-1,resenddata);

		SLF_sendMemBasePtr  sendData(new SLF_sendMemBase());
		sendData->m_mem = resenddata->m_data;
		_LOG_PROXYENCRYPT_INFO(m_id,"entrynet start req ,index:%d,uuid:%s",preq->m_index,slt_uuid_to_string(&preq->uuid).c_str());
		m_serversenderSptr->SLF_postMsg(m_parentSessID,_proxy_cmd_v2v_entrynetReq,getSessID(),sendData);
		return;
	}

	m_work_sub_state = en_work_sub_state_start;  //重新开始
	_LOG_PROXYENCRYPT_ERR(m_id,"entrynet send req error,nret:%X", nret);
}
void CProxyServiceCascade::OnRecvSynckeyResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	_proxy_cmd_v2v_syncKeyResp_st *presp = (_proxy_cmd_v2v_syncKeyResp_st*)_data->getData();
	_LOG_PROXYENCRYPT_DEBUG(m_id,"synckey resp ,index:%d,code:%X",presp->m_index,presp->code);
	if(! _checkResp(presp->m_index,presp->uuid)){
		return;
	}
	m_resendlist.del(presp->m_index);

	//应答失败，重新开始
	if(presp->code != 0){
		m_work_sub_state = en_work_sub_state_start;  //重新开始
		_LOG_PROXYENCRYPT_ERR(m_id,"synckey resp error,encrypt_code:%X",presp->encrypt_code);
		return;
	}

    SLT_memDataSptr memdata(SLT_memData::newData(4096));
	char *precvData = _data->getData() + sizeof(_proxy_cmd_v2v_syncKeyResp_st);
    int   recvlen = _data->getLen() - sizeof(_proxy_cmd_v2v_syncKeyResp_st);
    unsigned int temp = memdata->m_size - sizeof(_proxy_cmd_v2v_syncKeyReq_st);
	int nret = securev2v_syncKey(CProxyEncryptManage::getInst()->m_deviceHandle, 
	        	(unsigned char*)precvData, recvlen,(unsigned char*)memdata->m_pbuf + sizeof(_proxy_cmd_v2v_syncKeyResp_st), &temp);
    memdata->m_size = temp + sizeof(_proxy_cmd_v2v_syncKeyReq_st);

	if(nret == 0){
		//同步完成
		_LOG_PROXYENCRYPT_INFO(m_id,"synckey,success");
		_getZgkeyStart();
		return;
	}else if(nret == 0x0000AAAA){
		//发送同步命令
		//SLCS_sendReqData(_proxy_cmd_v2v_synckeyReq,std::to_string(_proxy_cmd_v2v_synckeyReq),1000,-1,memdata->m_pbuf,memdata->m_size,&req_index);
		_proxy_cmd_v2v_syncKeyReq_st *preq = (_proxy_cmd_v2v_syncKeyReq_st*)memdata->m_pbuf;
		preq->m_index = m_cmdindexbase++;
		preq->uuid = m_uuid;

		SLT_resendListUserDataSptr   resenddata = std::make_shared<SLT_resendListUserData>();
		resenddata->m_data.add(memdata->m_pbuf,memdata->m_size);
		m_resendlist.add2(preq->m_index,_proxy_cmd_v2v_synckeyReq,1000,-1,resenddata);

		SLF_sendMemBasePtr  sendData(new SLF_sendMemBase());
		sendData->m_mem = resenddata->m_data;
		_LOG_PROXYENCRYPT_INFO(m_id,"synckey start req ,index:%u",preq->m_index);
		m_serversenderSptr->SLF_postMsg(m_parentSessID,_proxy_cmd_v2v_synckeyReq,getSessID(),sendData);

		return;
	}

	m_work_sub_state = en_work_sub_state_start;  //重新开始
	_LOG_PROXYENCRYPT_ERR(m_id,"synckey send req error: %X", nret);
}
void CProxyServiceCascade::OnGetzgkeyResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	_proxy_cmd_v2v_getZgKeyResp_st *presp = (_proxy_cmd_v2v_getZgKeyResp_st*)_data->getData();
	_LOG_PROXYENCRYPT_DEBUG(m_id,"getzgkey resp ,index:%d,code:%X",presp->m_index,presp->code);
	if(! _checkResp(presp->m_index,presp->uuid)){
		return;
	}
	m_resendlist.del(presp->m_index);

	//应答失败，重新开始
	if(presp->code != 0){
		_LOG_PROXYENCRYPT_ERR(m_id,"getzgkey resp error,encrypt_code:%X",presp->encrypt_code);
		m_work_sub_state = en_work_sub_state_start;
		return;
	}

    SLT_memDataSptr memdata(SLT_memData::newData(4096));
	char *precvData = _data->getData() + sizeof(_proxy_cmd_v2v_getZgKeyResp_st);
    int   recvlen = _data->getLen() - sizeof(_proxy_cmd_v2v_getZgKeyResp_st);
	
	unsigned char traffid[32];   //接口要求，随便给个值就行,内部无关联
	traffid[0] = 2;
    int nret = securev2v_agreementZGKey(CProxyEncryptManage::getInst()->m_deviceHandle, traffid, sizeof(traffid),
        (unsigned char*)precvData, recvlen,
        (unsigned char*)memdata->m_pbuf, &memdata->m_size);
    
	if(nret == 0 || nret == 0x0000AAAF){
		//完成
		_LOG_PROXYENCRYPT_ERR(m_id,"getzgkey resp success,enret:%X",nret);
		m_work_state = encrypt_state_ok;
		m_localGetKeyNOtifyTimer.start();
	}else{
		_LOG_PROXYENCRYPT_ERR(m_id,"getzgkey resp error,ret:%X", nret);
		m_work_sub_state = en_work_sub_state_start;
		return;
	}
	//后面可以开始加解密数据了
	//securev2v_symEncrypt
	//securev2v_symDecrypt
}
void CProxyServiceCascade::OnLocalGetzgkeyReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	//接收通知间隔5s才触发key协商流程。
	if(m_localGetKeyNOtifyTimer.elapseMs() < 5000){
		return;
	}
	m_localGetKeyNOtifyTimer.start();

	//正在协商中，不处理
	if(! (m_work_state == encrypt_state_ok || m_work_state == encrypt_state_init)){
		return;
	}
	_entryNetStart();
}
void CProxyServiceCascade::_entryNetStart()
{
	m_work_state = encrypt_state_entrynet;
	m_work_sub_state = en_work_sub_state_start;

	SLT_memDataSptr memdata;
	int  nret = entryNetStart(memdata);
	if(nret != 0x0000AAAA){
		_LOG_PROXYENCRYPT_ERR(m_id,"entrynet start error : %X", nret);  //???失败了。我应该如何处理。重试吗？
		return;
	}

	//开始新的协商，重新分配uuid
	slt_uuid_create(&m_uuid);
	//清空缓存命令，重新开始
	m_resendlist.clear();
	m_parentSessID = 0;

	//开始发送数据
	m_work_sub_state = en_work_sub_state_wait;

	_proxy_cmd_v2v_entrynetReq_st *preq = (_proxy_cmd_v2v_entrynetReq_st*)memdata->m_pbuf;
	preq->uuid  = m_uuid;
	preq->m_index = m_cmdindexbase++;

	SLT_resendListUserDataSptr   resenddata = std::make_shared<SLT_resendListUserData>();
	resenddata->m_data.add(memdata->m_pbuf,memdata->m_size);
	m_resendlist.add2(preq->m_index,_proxy_cmd_v2v_entrynetReq,1000,-1,resenddata);

	if(!m_serversenderSptr){
		m_serversenderSptr = std::make_shared<CProxyMacSender>(CProxyEncryptManage::getInst());
		m_serversenderSptr->m_remoteMac = m_parentMac;
	}
	SLF_sendMemBasePtr  sendData(new SLF_sendMemBase());
	sendData->m_mem = resenddata->m_data;

	_LOG_PROXYENCRYPT_INFO(m_id,"entrynet start req ,index:%d,uuid:%s",preq->m_index,slt_uuid_to_string(&preq->uuid).c_str());
	m_serversenderSptr->SLF_postMsg(m_parentSessID,_proxy_cmd_v2v_entrynetReq,getSessID(),sendData);
	//SLCS_sendReqData(_proxy_cmd_v2v_entrynetReq,std::to_string(_proxy_cmd_v2v_entrynetReq), 1000,-1,memdata->m_pbuf,memdata->m_size,&reqIndex);
	
}
void CProxyServiceCascade::_syncKeyStart()
{
	m_work_state = encrypt_state_syckey;
	m_work_sub_state = en_work_sub_state_start;
	//开始同步key
	SLT_memDataSptr memdata;
	memdata.reset(SLT_memData::newData(4096));
	unsigned int   memdatalen = memdata->m_size - sizeof(_proxy_cmd_v2v_syncKeyReq_st);
	int nret = securev2v_syncKey(CProxyEncryptManage::getInst()->m_deviceHandle, NULL, 0,
		(unsigned char*)memdata->m_pbuf + sizeof(_proxy_cmd_v2v_syncKeyReq_st), &memdatalen);
	memdata->m_size = memdatalen + sizeof(_proxy_cmd_v2v_syncKeyReq_st);

	char* crepData = memdata->m_pbuf + sizeof(_proxy_cmd_v2v_syncKeyReq_st);
	std::string synckeyOutData =  SLT_AscToHex2(crepData,memdatalen);
	_LOG_PROXYENCRYPT_DEBUG(m_id,"synckey req datalen:%u,data:%s",memdatalen,synckeyOutData.c_str());

	if(nret == 0){
		//不同步
		_LOG_PROXYENCRYPT_INFO(m_id,"synckey start finish,success");
		_getZgkeyStart();
		return;
	}else if(nret == 0x0000AAAA){
		//发送同步命令
		m_work_sub_state = en_work_sub_state_wait;
		_proxy_cmd_v2v_syncKeyReq_st *preq = (_proxy_cmd_v2v_syncKeyReq_st*)memdata->m_pbuf;
		preq->m_index = m_cmdindexbase++;
		preq->uuid = m_uuid;

		SLT_resendListUserDataSptr   resenddata = std::make_shared<SLT_resendListUserData>();
		resenddata->m_data.add(memdata->m_pbuf,memdata->m_size);
		m_resendlist.add2(preq->m_index,_proxy_cmd_v2v_synckeyReq,1000,-1,resenddata);

		SLF_sendMemBasePtr  sendData(new SLF_sendMemBase());
		sendData->m_mem = resenddata->m_data;
		_LOG_PROXYENCRYPT_INFO(m_id,"synckey start req ,index:%u,senduuid:%s",preq->m_index,slt_uuid_to_string(&preq->uuid).c_str());
		std::string synckeyData =  SLT_AscToHex2(memdata->m_pbuf,memdata->m_size);
		_LOG_PROXYENCRYPT_DEBUG(m_id,"synckey req datalen:%u,alldata:%s",memdata->m_size,synckeyData.c_str());
		m_serversenderSptr->SLF_postMsg(m_parentSessID,_proxy_cmd_v2v_synckeyReq,getSessID(),sendData);
		//SLCS_sendReqData(_proxy_cmd_v2v_synckeyReq,std::to_string(_proxy_cmd_v2v_synckeyReq),1000,-1,memdata->m_pbuf,memdata->m_size,&req_index);
		return;
	}
		
	_LOG_PROXYENCRYPT_ERR(m_id,"synckey start req error, ret:%X", nret);
}
void CProxyServiceCascade::_getZgkeyStart()
{
	m_work_state = encrypt_state_getzgkey;
	m_work_sub_state = en_work_sub_state_start;

	//开始获取zgkey
	SLT_memDataSptr memdata(SLT_memData::newData(4096));
	unsigned int   memdatalen = memdata->m_size - sizeof(_proxy_cmd_v2v_getZgKeyReq_st);
	int nret = securev2v_agreementZGKey(CProxyEncryptManage::getInst()->m_deviceHandle, nullptr,0,nullptr,0,
			(unsigned char *)memdata->m_pbuf+ sizeof(_proxy_cmd_v2v_getZgKeyReq_st),&memdatalen);
	memdata->m_size = memdatalen + sizeof(_proxy_cmd_v2v_getZgKeyReq_st);
	dump_payload(memdata->m_pbuf + sizeof(_proxy_cmd_v2v_getZgKeyReq_st),100);
	if(nret == 0x0000AAAA){
		//发送同步命令
		m_work_sub_state = en_work_sub_state_wait;
		_proxy_cmd_v2v_getZgKeyReq_st *preq = (_proxy_cmd_v2v_getZgKeyReq_st*)memdata->m_pbuf;
		preq->m_index = m_cmdindexbase++;
		preq->uuid = m_uuid;

		SLT_resendListUserDataSptr   resenddata = std::make_shared<SLT_resendListUserData>();
		resenddata->m_data.add(memdata->m_pbuf,memdata->m_size);
		m_resendlist.add2(preq->m_index,_proxy_cmd_v2v_zgkeyReq,1000,-1,resenddata);

		SLF_sendMemBasePtr  sendData(new SLF_sendMemBase());
		sendData->m_mem = resenddata->m_data;
		//SLCS_sendReqData(_proxy_cmd_v2v_zgkeyReq,std::to_string(_proxy_cmd_v2v_zgkeyReq),1000,-1,memdata->m_pbuf,memdata->m_size,&req_index);
		_LOG_PROXYENCRYPT_INFO(m_id,"getzgkey start req ,index:%u",preq->m_index);
		_LOG_PROXYENCRYPT_DEBUG(m_id,"getzgkey start,memdatalen:%u",memdata->m_size);
		m_serversenderSptr->SLF_postMsg(m_parentSessID,_proxy_cmd_v2v_zgkeyReq,getSessID(),sendData);
		return;
	}
	_LOG_PROXYENCRYPT_ERR(m_id,"getzgkey start req error,ret:%X", nret);  //???失败了。我应该如何处理。重试吗？
}
/*************************************************************************************************************************************************/
CProxyEncryptManage* CProxyEncryptManage::getInst()
{
	static CProxyEncryptManage *g_pem = nullptr;
	static std::once_flag  of;
	if(! g_pem){
		std::call_once(of,[](){
			g_pem = new CProxyEncryptManage();
		});
	}
	return g_pem;
}
bool  CProxyEncryptManage::isSupportEncrypt()
{
#ifdef PROXYENCRYPT
	return true;
#else
	return false;
#endif
}
int CProxyEncryptManage::init(ManageProxy* proxy)
{
	#ifndef PROXYENCRYPT
	{
		_LOG_PROXYENCRYPT_ERR(0,"ProxyEncrypt not support!!!!!!");
		return 0;
	}
	#endif
	//加密协商是由子级触发的。如果没有配置upmac，不会触发秘钥协商流程
	//父级需要具备协商秘钥的能力，
	//发送的数据是否加密，配置在虚拟网卡上
	// if(0 == configure::instance()->get_encrypt())
	// {
	// 	_LOG_PROXYENCRYPT_DEBUG(0,"encrypt is 0 no need GetKey");
	// 	return 0;
	// }

	SECURE_INIT vvsecinit;
	vvsecinit.pConfFilePath = (char*)"./etc/";
	vvsecinit.uConfFilePathLen = strlen((char*)vvsecinit.pConfFilePath);
	int nret = VVSec_Initlize(&vvsecinit);
	if(nret != 0) {
		_LOG_PROXYENCRYPT_ERR(0,"VVSec_Initlize error : %X", nret);
		return -1;
	}
    
	int nDeviceId = 110;
	nret = VVSec_OpenDevice(nDeviceId, &m_deviceHandle);
	if(nret != 0){
		_LOG_PROXYENCRYPT_ERR(0,"VVSec_OpenDevice error : %X", nret);
		return -2;
	}

	PKI_DATA pinData;
	nret = VVSec_LoginDevice(m_deviceHandle, pinData);
	if(nret != 0){
		_LOG_PROXYENCRYPT_ERR(0,"VVSec_LoginDevice error : %X", nret);
		return -3;
	}

    m_pManageProxy = proxy;
    m_pManageProxy->SubscribeData(std::bind(&CProxyEncryptManage::recvMacData, this, std::placeholders::_1, std::placeholders::_2));

	if(configure::instance()->m_config.up_mac.empty()){
		_LOG_PROXYENCRYPT_ERR(0,"config up mac null");

		//使用密管或代理，异步初始化加密中间件,进程启动成功一次就可以了
		CProxyEncryptInitSession *psession = new CProxyEncryptInitSession();
		SLF_SessionBasePtr bsSptr(psession);
		psession->proxy_ip = configure::instance()->m_config.v2vproxy_ip;
		psession->proxy_port = configure::instance()->m_config.v2vproxy_port;
		SLF_addSession(bsSptr);

		return 0;
	}

	//通过上级协商秘钥，并初始化加密中间件
    int tempValue[6] = { 0 },ret = 0;
    if (6 != (ret = sscanf(configure::instance()->m_config.up_mac.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x",
        &tempValue[0], &tempValue[1], &tempValue[2], &tempValue[3], &tempValue[4], &tempValue[5]
    ))){
		_LOG_PROXYENCRYPT_ERR(0,"config up mac error : %s", configure::instance()->m_config.up_mac.c_str());
		return -4;
	}
    
	m_parentSession = std::make_shared<CProxyServiceCascade>();
	for (uint8_t i = 0; i < 6; ++i) m_parentSession->m_parentMac[i] = tempValue[i];
	_LOG_PROXYENCRYPT_DEBUG(0,"config up mac:%s",m_parentSession->m_parentMac.toString().c_str());

	//同时开始秘钥协商
	SLF_addSession(m_parentSession);

	return 0;
}
void  CProxyEncryptManage::startGetKey()
{
	if(m_parentSession){
		SLF_postMsg(m_parentSession->getSessID(),_proxy_cmd_local_startZgkey,0,SLF_sendMemBasePtr());
	}
}
void CProxyEncryptManage::recvConnect(MacType &_remoteMac, const SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data)
{
	//服务器方: 处理连接请求，创建子对象
	_proxy_cmd_v2v_entrynetReq_st *preq = (_proxy_cmd_v2v_entrynetReq_st*)_data->getData();

	std::unique_lock<std::mutex>  l(m_childLock);
	//使用自治前缀为key
	auto mIter = m_childs.find(_remoteMac);
	CProxyServiceCascadeChildSptr childSptr;
	if(mIter == m_childs.end()){
		//创建子节点
		childSptr = std::make_shared<CProxyServiceCascadeChild>();
		_LOG_PROXYENCRYPT_ERR(0,"add child mac:%s,guid:%s",_remoteMac.toString().c_str(),slt_uuid_to_string(&preq->uuid).c_str());
		childSptr->m_remotemac = _remoteMac;
		SLF_addSession(childSptr);
		m_childs.insert(std::make_pair(_remoteMac,childSptr));
	}else{
		childSptr = mIter->second;
	}

	SLF_pushEvent(childSptr->getSessID(),msgid,srcSid,_data,_sender);
}
void  CProxyEncryptManage::delchild(CProxyServiceCascadeChild *pchild)
{
	SLF_delSession(pchild->getSessID());

	_LOG_PROXYENCRYPT_ERR(0,"del child :%s,guid:%s",pchild->m_remotemac.toString().c_str(),slt_uuid_to_string(&pchild->m_uuid).c_str());
	std::unique_lock<std::mutex>  l(m_childLock);
	m_childs.erase(pchild->m_remotemac);
}
void CProxyEncryptManage::recvMacData(MacType addr, DataCache data)
{
    _LOG_PROXYENCRYPT_ERR(0, "recv data len : %d", data.size());

    dump_payload(data(), data.size());
	//接收到数据,通过消息处理数据
	SLTMacSenderProtocolHeadSt *phead = (SLTMacSenderProtocolHeadSt*)data();
	phead->toLocal();

	CProxyMacSenderPtr sender2 = std::make_shared<CProxyMacSender>(this);
	sender2->m_remoteMac = addr;

	SLF_sendMemBasePtr memdata(new SLF_sendMemBase());
	memdata->add(data() + sizeof(SLTMacSenderProtocolHeadSt),data.size() - sizeof(SLTMacSenderProtocolHeadSt));

	if(_proxy_cmd_v2v_entrynetReq == phead->m_cmd){
		//子级第一个入网请求
        recvConnect(addr, sender2, phead->m_srcid, phead->m_cmd, memdata);
	}else{
		SLF_pushEvent(phead->m_dstid,phead->m_cmd,phead->m_srcid,memdata,sender2);
	}
}

void CProxyEncryptManage::sendMacData(MacType addr, DataCache& data)
{
	//发送数据
    m_pManageProxy->SendGeneralData(addr, std::move(data));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CProxyMacSender::SLF_postMsg(uint32_t _SessID, int msgid, uint32_t _srcID,const SLF_sendMemBasePtr &_data)
{
	SLTMacSenderProtocolHeadSt head;
	head.m_cmd = msgid;
	head.m_dstid = _SessID;
	head.m_len = sizeof(SLTMacSenderProtocolHeadSt)+ _data->getLen();
	head.m_srcid = _srcID;
	head.toNet();

	SLT_memBuf  senddata;
	senddata.resize(sizeof(SLTMacSenderProtocolHeadSt)+ _data->getLen());
	senddata.append((char*)&head,sizeof(SLTMacSenderProtocolHeadSt));
	senddata.append(_data->getData(),_data->getLen());

	DataCache datacache(senddata.getLen());
	datacache.set(senddata.getLen());
	memcpy(datacache(),senddata.get(),senddata.getLen());
	SLT_LOG_ERR("SLF_postMsg sendlen：%d,datacache len:%d",senddata.getLen(),datacache.size());

    _LOG_PROXYENCRYPT_ERR(0, "send data len : %d", datacache.size());
    dump_payload(datacache(), datacache.size());
	m_pManage->sendMacData(m_remoteMac,datacache);
	return true;
}